// 封装axios的请求，返回重新封装的数据格式
// 对错误统一处理
// 拦截器加入token
import axios from 'axios';
import errHandle from './errHandle';
import store from '@/store';
import publicConfig from '@/config';

const CancelToken = axios.CancelToken;

class httpRequest {
  constructor (baseURL) {
    this.baseURL = baseURL;
    // 全局变量存储当前的url，取消请求时使用
    this.pending = {};
  }

  // 获取axios的相关配置
  getInsideConfig () {
    const config = {
      baseURL: this.baseURL,
      headers: {
        'Content-Type': 'application/json;charset=utf-8'
      },
      // 设置10秒的超时时间，超过则断定请求失败
      timeout: 10000
    };
    return config;
  }

  removePending (key, isRequest = false) {
    if (this.pending[key] && isRequest) {
      this.pending[key]('取消重复请求');
    }
    delete this.pending[key];
  }

  // 设定拦截器
  setInterceptors (instance) {
    instance.interceptors.request.use((config) => {
      // 在发送请求之前做些什么
      let key = config.url + '&' + config.method;
      this.removePending(key);
      config.cancelToken = new CancelToken((c) => {
        this.pending[key] = c;
      });

      let isPublic = false;
      publicConfig.publicPath.map(path => {
        isPublic = path.test(config.url);
      });
      if (!isPublic) {
        if (store.state.token) {
          // const headers = {
          //   Authorization: 'Bearer ' + store.state.token,
          //   'Content-type': 'application/json'
          // };
          config.headers.Authorization = 'Bearer ' + store.state.token;
          config.headers['Content-type'] = 'application/json';
        }
      }

      return config;
    }, function (error) {
      errHandle(error);
      // 对请求错误做些什么
      return Promise.reject(error);
    });

    // 添加响应拦截器
    instance.interceptors.response.use((response) => {
      // 对响应数据做点什么
      let key = response.config.url + '&' + response.config.method;
      this.removePending(key, true);
      if (response.status === 200) {
        return Promise.resolve(response.data);
      } else {
        return Promise.reject(response);
      }
    }, function (error) {
      errHandle(error);
      // 对响应错误做点什么
      return Promise.reject(error);
    });
  }

  // 创建实例
  request (options) {
    // 自定义axios实例并配置
    const instance = axios.create();
    // 获取最新的配置项信息
    const newOptions = Object.assign(this.getInsideConfig(), options);
    // 设置自定义axios的拦截器
    this.setInterceptors(instance);
    // 这里相当于axios.create().request()的简写
    return instance(newOptions);
  }

  // get请求的封装
  get (url, config) {
    const newOptions = Object.assign({
      method: 'get',
      url: url
    }, config);
    return this.request(newOptions);
  }

  // post请求的封装
  post (url, data, config) {
    const newOptions = Object.assign({
      method: 'post',
      url: url,
      data: data
    }, config);
    return this.request(newOptions);
  }
}

export default httpRequest;
